﻿using System.Collections;
using UnityEngine;
using System.Collections.Generic;
using System;

/// <summary>
/// A*算法
/// </summary>
public class AStar
{
    private bool canReach;
    private GridScript[,] map;
    private GridScript start;
    private GridScript end;
    private List<GridScript> openList;
    private List<GridScript> closeList;

    public AStar(GridScript[,] map, GridScript start, GridScript end)
    {
        this.map = map;
        this.start = start;
        this.end = end;
        openList = new List<GridScript>();
        closeList = new List<GridScript>();
    }

    #region   寻路      
    public void FindWay()
    {
        openList.Add(start);  //将当前点添加到openlist
        while (openList.Count > 0)
        {
            GridScript first = openList[0];
            for (int i = 0; i < 8; i++)
            {
                GridScript g = GetRoundGrid(first, i);
                if (IsOK(g))
                {
                        g.Visited = true;
                        openList.Add(g);
                        SetLink(first, g);
				    if(g.X == end.X && g.Y == end.Y)
                    {
                        canReach = true;
                        return;
                    }
                }
            }
            openList.Remove(first);
            closeList.Add(first); //将当前点添加到closelist
            openList.Sort(new ComparerByFValue());
        }
    }
    int[,] _dir = new int[,]
    {
        {0,0},{0,1},
          {1,0},{1,1},
            {0,-1},{1,-1},
                {-1,0},{-1,1},
    };
    public GridScript GetRoundGrid(GridScript grid,int index)
    {
        int x = grid.X + _dir[index, 0];
        int y = grid.Y + _dir[index, 1];
        if (x < 0 || y < 0 || x >= map.GetLength(0) || y >= map.GetLength(1))
        {
            return null;
        }
        if (map[x, y].gridType == GridType.Obstacle)
        {
            return null;
        }
        return map[x, y];
    }

    public bool IsOK(GridScript grid)
    {
        if (grid == null)
        {
            return false;
        }
        if (closeList.Contains(grid))
        {
            return false;
        }
        //if (grid.gridType == GridType.Obstacle)
        //{
        //    return false;
        //}
        return true;
    }

    public void SetLink(GridScript parent, GridScript son)
    {
        son.Parent = parent;
        son.CalG(parent, end);
    }
    #endregion

    public void Print()
    {
        Debug.Log(canReach);
    }
}

 class ComparerByFValue : IComparer<GridScript>
{
     public int Compare(GridScript x, GridScript y)
     {
         if (x.F > y.F)
             return 1;
         return -1;
     }
}
